import Cocoa
//Swift高阶函数 https://www.jianshu.com/p/dabd885bf100


// sort
// 准备一个数组
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
// 这种默认是升序
array.sorted()
// 如果降序
array.sorted(by: >)

// forEach
var companies: [String] = ["Alipay", "Baby", "Apple", "Google", "Baidu"]
companies.forEach { item in
  print(item)
}

// reduce: 合规

// map和filter方法都是通过一个已存在的数组，生成一个新的、经过修改的数组。然而有时候我们需要把所有元素的值合并成一个新的值
var sum: [Int] = [1, 2, 3, 4]
// reduce 函数第一个参数是返回值的初始化值 result是中间结果 num是遍历集合每次传进来的值
var total = sum.reduce(20) { result, num -> Int in
  result + num
}

print(total)

// first(where:) last(where:)
var fruits: [String] = ["banana", "apple", "tomato", "pineapple"]
if let hasP = fruits.first(where: { $0.hasPrefix("p") }) { print(hasP + " has literal p.") }
if let hasT = fruits.last(where: { $0.hasPrefix("5") }) { print(hasT) }

// removeAll(where:)
fruits.removeAll(where: { $0.hasPrefix("p") })
print(fruits)

// allSatisfy 条件符合（Swift 4.2）
// 判断数组的所有元素是否全部大于85
// 检查序列中的所有元素是否满足条件，返回 Bool
let scores = [86, 88, 95, 92]
let passed = scores.allSatisfy { $0 > 80 }
print(passed)

// mapValues
let dic: [String: Int] = [
  "first": 1,
  "second": 2,
  "three": 3,
  "four": 4
]
// 字典中的函数, 对字典的value值执行操作, 返回改变value后的新的字典
let mapValues = dic.mapValues { $0 + 2 }

print(mapValues)
// compactMapValues
let compactDic: [String: String] = [
  "first": "1",
  "second": "2",
  "three": "3",
  "four": "4",
  "five": "abc"
]
// 将上述两个方法的功能合并在一起，返回一个对value操作后的新字典， 并且自动过滤不符合条件的键值对
let newDic = compactDic.compactMapValues { Int($0) }
print(newDic)

// map
let arrayAny: [Any?] = [1, 2, 3, 4, 5, nil, "a", 8, "9"]
print(arrayAny)
let arrInt = arrayAny.map { obj -> Int in
  if obj is Int {
    return obj as! Int
  } else {
    return 0
  }
}

print("arrInt: \(arrInt)")
// arrInt: [1, 2, 3, 4, 5, 0, 0, 8, 0]

let arrInt2 = arrayAny.map {
  ($0 is Int) ? $0 : 0
}

print("arrInt2: \(arrInt2)")
// arrInt2: [Optional(1), Optional(2), Optional(3), Optional(4), Optional(5), Optional(0), Optional(0), Optional(8), Optional(0)]

// flatmap

// 例1：flatMap 对最终的结果进行了所谓的 “降维” 操作
let numbersCompound = [[1, 2, 3], [4, 5, 6]]
var res = numbersCompound.map { $0.map { $0 + 2 } }
// [[3, 4, 5], [6, 7, 8]]
var flatRes = numbersCompound.flatMap { $0.map { $0 + 2 } }
// [3, 4, 5, 6, 7, 8]

// 例2：将原数组中的 nil 值过滤掉了，所有元素都被解包了
let optionalArray: [String?] = ["AA", nil, "BB", "CC"]
print(optionalArray)
// [Optional("AA"), nil, Optional("BB"), Optional("CC")]

// 可选数组不推荐使用flatMap,请使用compactMap
// var optionalResult = optionalArray.flatMap{ $0 }
var optionalResult = optionalArray.compactMap { $0 }
print(optionalResult)
// ["AA", "BB", "CC"]
// filter
// compactMap
